/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.zhpan.bannerview.base;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.PageSlider;
import ohos.agp.components.PageSliderProvider;
import ohos.agp.utils.Color;
import ohos.app.Context;

import com.zhpan.bannerview.options.IndicatorOptions;
import com.zhpan.bannerview.options.Options;

/**
 * BaseIndicatorComponent
 *
 * @since 2021-03-24
 */
public class BaseIndicatorComponent extends Component implements IIndicator {
    /**
     * mIndicatorOptions
     */
    protected IndicatorOptions mIndicatorOptions;
    private PageSlider mPageSlide;
    private int pageSize;
    private boolean isLoop = true;

    /**
     * BaseIndicatorComponent
     *
     * @param context 參數
     */
    public BaseIndicatorComponent(Context context) {
        this(context, null);
    }

    /**
     * BaseIndicatorComponent
     *
     * @param context 參數
     * @param attrSet 參數
     */
    public BaseIndicatorComponent(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    /**
     * BaseIndicatorComponent
     *
     * @param context 參數
     * @param attrSet 參數
     * @param styleName 參數
     */
    public BaseIndicatorComponent(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        mIndicatorOptions = new IndicatorOptions(getContext());
    }

    @Override
    public void notifyDataChanged() {
        setupViewPager();
        pageSize = getPageSize();
        mIndicatorOptions.setRealPosition(mPageSlide.getCurrentPage());
        postLayout();
        invalidate();
    }

    @Override
    public void setIndicatorOptions(IndicatorOptions options) {
        mIndicatorOptions = options;
    }

    @Override
    public void onPageSliding(int position, float positionOffset, int offsetPixels) {
        if (getSlideMode() != Options.IndicatorMode.NORMAL && pageSize > 1) {
            if (position == getPageSize() - 1 && isLoop) {
                setCurrentPage(0);
                setSlideProgress(0);
                invalidate();
            } else {
                if (offsetPixels < 0) {
                    position = position - 1;
                    positionOffset = 1 - positionOffset;
                }
                scrollSlider(position, positionOffset);
                invalidate();
            }
        }
    }

    /**
     * isLoop
     *
     * @param loop 參數
     */
    public void isLoop(boolean loop) {
        this.isLoop = loop;
    }


    @Override
    public void onPageSlideStateChanged(int state) {
    }

    @Override
    public void onPageChosen(int position) {
        if (getSlideMode() == Options.IndicatorMode.NORMAL) {
            setCurrentPosition(position);
            setSlideProgress(0f);
            invalidate();
        }
    }

    /**
     * 无限轮播的时候 需要调用此方法
     * <p>
     * indicator.setCurrentPage();
     * pageSlide.setCurrentPage();
     *
     * @param position 參數
     */
    public void setCurrentPage(int position) {
        if (position == 0) {
            setSlideProgress(0);
            setCurrentPosition(0);
        }
    }

    private void setupViewPager() {
        if (mPageSlide != null) {
            try { // mPageSlide.removePageChangedListener(this);
                mPageSlide.addPageChangedListener(this);
                PageSliderProvider provider = mPageSlide.getProvider();
                if (provider != null) {
                    setPageSize(provider.getCount());
                }
            } catch (Exception e) { // dicatorComponent@4415fe9 was not registered.
            }
        }
    }

    /**
     * 手指←←←←←←←← 滑动 offset 0 - 1 的状态
     * 手指→→→→→→→→ 滑动 offset 1 - 0 的变化
     *
     * @param position 是当前被拖动的位置
     * @param positionOffset positionOffset
     */
    private void scrollSlider(int position, float positionOffset) {
        int slideMode = mIndicatorOptions.getSlideMode();
        if (slideMode == Options.IndicatorMode.SCALE
            || slideMode == Options.IndicatorMode.COLOR) {
            setCurrentPosition(position);
            setSlideProgress(positionOffset);
        } else {
            if (position % getPageSize() == getPageSize() - 1) {
                if (positionOffset < 0.5) {
                    setCurrentPosition(position);
                    setSlideProgress(0f);
                } else {
                    setCurrentPosition(0);
                    setSlideProgress(0f);
                }
            } else { // 中间页面
                setCurrentPosition(position);
                setSlideProgress(positionOffset);
            }
        }
    }

    /**
     * setupWithPageSlide
     *
     * @param pageSlider 參數
     */
    public void setupWithPageSlide(PageSlider pageSlider) {
        this.mPageSlide = pageSlider;
        notifyDataChanged();
    }

    /**
     * getOrientation
     *
     * @return int
     */
    public int getOrientation() {
        return mIndicatorOptions.getOrientation();
    }

    /**
     * setOrientation
     *
     * @param orientation 參數
     */
    public void setOrientation(int orientation) {
        this.mIndicatorOptions.setOrientation(orientation);
    }

    /**
     * getIndicatorStyle
     *
     * @return int
     */
    public int getIndicatorStyle() {
        return mIndicatorOptions.getIndicatorStyle();
    }

    /**
     * setIndicatorStyle
     *
     * @param indicatorStyle 參數
     */
    public void setIndicatorStyle(int indicatorStyle) {
        this.mIndicatorOptions.setIndicatorStyle(indicatorStyle);
    }

    /**
     * getSlideMode
     *
     * @return int
     */
    public int getSlideMode() {
        return mIndicatorOptions.getSlideMode();
    }

    /**
     * setSlideMode
     *
     * @param slideMode 參數
     */
    public void setSlideMode(int slideMode) {
        this.mIndicatorOptions.setSlideMode(slideMode);
    }

    /**
     * getPageSize
     *
     * @return int
     */
    public int getPageSize() {
        return mIndicatorOptions.getPageSize();
    }

    /**
     * setPageSize
     *
     * @param pageSize 參數
     */
    public void setPageSize(int pageSize) {
        this.mIndicatorOptions.setPageSize(pageSize);
    }

    /**
     * getNormalSliderColor
     *
     * @return Color
     */
    public Color getNormalSliderColor() {
        return mIndicatorOptions.getNormalSliderColor();
    }

    /**
     * setNormalSliderColor
     *
     * @param normalSliderColor 參數
     */
    public void setNormalSliderColor(Color normalSliderColor) {
        this.mIndicatorOptions.setNormalSliderColor(normalSliderColor);
    }

    /**
     * getCheckedSliderColor
     *
     * @return Color
     */
    public Color getCheckedSliderColor() {
        return mIndicatorOptions.getCheckedSliderColor();
    }

    /**
     * setCheckedSliderColor
     *
     * @param checkedSliderColor 參數
     */
    public void setCheckedSliderColor(Color checkedSliderColor) {
        this.mIndicatorOptions.setCheckedSliderColor(checkedSliderColor);
    }

    /**
     * getSliderGap
     *
     * @return float
     */
    public float getSliderGap() {
        return mIndicatorOptions.getSliderGap();
    }

    /**
     * setSliderGap
     *
     * @param sliderGap 參數
     */
    public void setSliderGap(float sliderGap) {
        this.mIndicatorOptions.setSliderGap(sliderGap);
    }

    /**
     * getSliderHeight
     *
     * @return float
     */
    public float getSliderHeight() {
        return mIndicatorOptions.getSliderHeight();
    }

    /**
     * setSliderHeight
     *
     * @param sliderHeight 參數
     */
    public void setSliderHeight(float sliderHeight) {
        this.mIndicatorOptions.setSliderHeight(sliderHeight);
    }

    /**
     * setSliderWidth
     *
     * @param normalIndicatorWidth 參數
     * @param checkedIndicatorWidth 參數
     */
    public void setSliderWidth(float normalIndicatorWidth, float checkedIndicatorWidth) {
        this.mIndicatorOptions.setSliderWidth(normalIndicatorWidth, checkedIndicatorWidth);
    }

    /**
     * setSliderWidth
     *
     * @param width 參數
     */
    public void setSliderWidth(float width) {
        setSliderWidth(width, width);
    }

    /**
     * getNormalSliderWidth
     *
     * @return float
     */
    public float getNormalSliderWidth() {
        return mIndicatorOptions.getNormalSliderWidth();
    }

    /**
     * setNormalSliderWidth
     *
     * @param normalSliderWidth 參數
     */
    public void setNormalSliderWidth(float normalSliderWidth) {
        this.mIndicatorOptions.setNormalSliderWidth(normalSliderWidth);
    }

    /**
     * getCheckedSliderWidth
     *
     * @return float
     */
    public float getCheckedSliderWidth() {
        return mIndicatorOptions.getCheckedSliderWidth();
    }

    /**
     * setCheckedSliderWidth
     *
     * @param checkedSliderWidth 參數
     */
    public void setCheckedSliderWidth(float checkedSliderWidth) {
        this.mIndicatorOptions.setCheckedSliderWidth(checkedSliderWidth);
    }

    /**
     * getCurrentPosition
     *
     * @return int
     */
    public int getCurrentPosition() {
        return mIndicatorOptions.getCurrentPosition();
    }

    /**
     * setCurrentPosition
     *
     * @param currentPosition 參數
     */
    public void setCurrentPosition(int currentPosition) {
        this.mIndicatorOptions.setCurrentPosition(currentPosition);
        this.mIndicatorOptions.setRealPosition(currentPosition);
    }

    /**
     * getSlideProgress
     *
     * @return float
     */
    public float getSlideProgress() {
        return mIndicatorOptions.getSlideProgress();
    }

    /**
     * setSlideProgress
     *
     * @param slideProgress 參數
     */
    public void setSlideProgress(float slideProgress) {
        this.mIndicatorOptions.setSlideProgress(slideProgress);
    }

}
